﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace VideoClipNameHelper
{
    public class CleanFileName
    {
        //===========================================================================================================================
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fnWoPathExt">File name WITHOUT path and WITHOUT EXT</param>
        /// <returns></returns>
        public static string CleanName(string fnWoPathExt, bool isCheckResolution = true)
        {
            VideoClipData vcd = new VideoClipData();
            try
            {
                fnWoPathExt = CleanStringFromUnicodeVariants(fnWoPathExt);
                //Console.WriteLine("fnWoPathExt[{0}]", fnWoPathExt);
                fnWoPathExt = CleanStringSimply(fnWoPathExt);
                //Console.WriteLine("fnWoPathExt[{0}]", fnWoPathExt);
                //
                if ("" != VideoClipNameHelper.VideoClipData.Parse(fnWoPathExt, vcd, isCheckResolution))
                {
                    return CleanPartOfName(fnWoPathExt);
                }
                //Console.WriteLine("vcd[{0}]", vcd.ToString());
                //fnWoPathExt = System.IO.Path.GetFileNameWithoutExtension(fnWoPathExt);
                //
                if ("" == fnWoPathExt)
                {
                    return "_";
                }
                //
                if (0 == vcd.Artists.Count)
                {
                    //vcd.Artist = CleanPartOfName(vcd.Artist);
                    vcd.Artist = CleanPartOfName(VideoClipNameHelper.Articles.GetNameWithArticle(vcd.Artist));
                    vcd.Artist = movePrefix(vcd.Artist);
                }
                else
                {
                    for(int i=0; i< vcd.Artists.Count;i++)
                    {
                        //vcd.Artists[i].Item = CleanPartOfName(vcd.Artists[i].Item);
                        vcd.Artists[i] = CleanPartOfName(VideoClipNameHelper.Articles.GetNameWithArticle(vcd.Artists[i]));
                        vcd.Artists[i] = movePrefix(vcd.Artists[i]);
                    }
                }
                //
                vcd.Album = CleanPartOfName(vcd.Album);
                //
                vcd.Title = CleanPartOfName(vcd.Title);
                //
                for (int i = 0; i < vcd.TitleExtras.Count; i++)
                {
                    vcd.TitleExtras[i] = CleanPartOfName(vcd.TitleExtras[i]);
                }
                //
                //Console.WriteLine("vcd[{0}]", vcd.ToString());
                //Console.WriteLine("vcd[{0}]", vcd.Concat());
                return vcd.Concat();
            }
            catch (Exception e)
            {
                string msg = e.Message;//dummy
                //Console.WriteLine("msg[{0}]", msg);
                return CleanPartOfName(fnWoPathExt);
            }
            //
            return fnWoPathExt;
        }
        //===========================================================================================================================
        public static string CleanPartOfName(string part)
        {
            //string[] tokens = part.Split(new[] { ' ' });
            List<string> tokens = new List<string>();
            tokens.AddRange(part.Split(new[] { ' ' }));
            //
            for (int i = 0; i < tokens.Count; i++)
            {
                tokens[i] = ToCamelIfNeeded(tokens[i]);
            }

            return string.Join(" ", tokens);
        }
        //===========================================================================================================================
        public static string CleanStringSimply(string fnWoPathExt)
        {
            //fnWoPathExt = fnWoPathExt.Replace('_', ' ');
            fnWoPathExt = fnWoPathExt.Replace('.', ' ');
            fnWoPathExt = fnWoPathExt.Replace(" @ ", "@");
            fnWoPathExt = fnWoPathExt.Replace("( ", "(");
            fnWoPathExt = fnWoPathExt.Replace(" )", ")");
            fnWoPathExt = fnWoPathExt.Replace("[ ", "[");
            fnWoPathExt = fnWoPathExt.Replace(" ]", "]");
            fnWoPathExt = fnWoPathExt.Replace("  ", " ");
            //
            return fnWoPathExt.Trim();
        }
        //===========================================================================================================================
        public static string CleanStringFromUnicodeVariants(string s)
        {//`````’’
            return s
.Replace('`', '\'')//
.Replace('‘', '\'')//    U+2018 (alt-08216) LEFT SINGLE QUOTATION MARK = single turned comma quotation mark 
.Replace('’', '\'')//    U+2019 (alt-08217) RIGHT SINGLE QUOTATION MARK = single comma quotation mark 
.Replace('‚', '\'')//    U+201A (alt-08218) SINGLE LOW-9 QUOTATION MARK = low single comma quotation mark 
.Replace('‛', '\'')//    U+201B (alt-08219) SINGLE HIGH-REVERSED-9 QUOTATION MARK = single reversed comma quotation mark 
.Replace('“', '\"')//    U+201C (alt-08220) LEFT DOUBLE QUOTATION MARK = double turned comma quotation mark 
.Replace('”', '\"')//    U+201D (alt-08221) RIGHT DOUBLE QUOTATION MARK = double comma quotation mark 
.Replace('„', '\"')//    U+201E (alt-08222) DOUBLE LOW-9 QUOTATION MARK = low double comma quotation mark 
.Replace('‟', '\"')//    U+201F (alt-08223) DOUBLE HIGH-REVERSED-9 QUOTATION MARK = double reversed comma quotation mark 
.Replace('‐', '-')//    U+2010 (alt-08208) HYPHEN 
.Replace('‑', '-')//    U+2011 (alt-08209) NON-BREAKING HYPHEN 
.Replace('‒', '-')//    U+2012 (alt-08210) FIGURE DASH 
.Replace('–', '-')//    U+2013 (alt-08211) EN DASH 
.Replace('—', '-')//    U+2014 (alt-08212) EM DASH 
.Replace('―', '-');//    U+2015 (alt-08213) HORIZONTAL BAR = quotation dash 
        }
        //===========================================================================================================================
        public static string RenameIllegalSystemChars(string s)
        {
            string o = "";
            //
            foreach (char c in s)
            {
                // : ＊ ＜＞／＼ ｜？
                switch (c)
                {
                    case '"':    //U+FF02 (alt-065282) FULLWIDTH QUOTATION MARK
                        o += '＂'; break;
                    case '.':    //U+FF0E (alt-065294) FULLWIDTH FULL STOP
                        o += '．'; break;
                    case ':':    //U+FF1A (alt-065306) FULLWIDTH COLON
                        o += '：'; break;
                    case '?':    //U+FF1F (alt-065311) FULLWIDTH QUESTION MARK
                        o += '？'; break;
                    case '*':    //U+FF0A (alt-065290) FULLWIDTH ASTERISK
                        o += '＊'; break;
                    case '<':    //U+FF1C (alt-065308) FULLWIDTH LESS-THAN SIGN
                        o += '＜'; break;
                    case '>':    //U+FF1E (alt-065310) FULLWIDTH GREATER-THAN SIGN
                        o += '＞'; break;
                    case '/':    //U+FF0F (alt-065295) FULLWIDTH SOLIDUS
                        o += '／'; break;
                    case '\\':    //U+FF3C (alt-065340) FULLWIDTH REVERSE SOLIDUS
                        o += '＼'; break;
                    //￤   //U+FFE4 (alt-065508) FULLWIDTH BROKEN BAR
                    case '|':    //U+FF5C (alt-065372) FULLWIDTH VERTICAL LINE
                        o += '｜'; break;
                    default:
                        o += c;
                        break;
                }
            }
            //
            return o;
        }
        //===========================================================================================================================
        private static System.Globalization.TextInfo ti = System.Globalization.CultureInfo.InvariantCulture.TextInfo;

        private static string ToCamelIfNeeded(string src)
        {
            if ((src == ti.ToLower(src)) || (src == ti.ToUpper(src)))
            {
                src = ti.ToTitleCase(ti.ToLower(src));
            }
            return src;
        }
        //===========================================================================================================================
        public readonly static string[] Prefixes = { "The ", "A ", "Die ", "Der " };
        private static string movePrefix(string name)
        {
            foreach (string prefix in Prefixes)
            {
                if (name.Length > prefix.Length + 1)
                {
                    if (name.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
                    {
                        string namePrefix = name.Substring(0, prefix.Length - 1);
                        string nameWithoutPrefix = name.Substring(prefix.Length);
                        return nameWithoutPrefix + ", " + namePrefix;
                    }
                }
            }
            return name;
        }
        //===========================================================================================================================

    }//class
}//namespace
